<template>
  <div class="lb-table">
    <search-form
      :column="column"
      :showExpandFormFlag="this.showExpandFormFlag"
      @searchAction="haneleSearch"></search-form>
    <el-table
      ref="elTable"
      stripe
      v-bind="$attrs"
      v-on="$listeners"
      :data="tableData"
      v-loading="loading"
      size="small"
      show-summary
      :summary-method="getTotal"
      :span-method="this.merge ? this.mergeMethod : this.spanMethod">
      <lb-column
        v-bind="$attrs"
        v-for="(item, index) in column"
        :key="index"
        :column="item"></lb-column>
    </el-table>
    <el-pagination
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="pageInfo.currentPage"
      :page-sizes="pageInfo.pageOptions"
      :page-size="pageInfo.pageSize"
      layout="total,sizes, prev, pager, next, jumper, slot"
      :total="pageInfo.total"
      :style="{ 'margin-top': paginationTop, 'text-align': paginationAlign }">
      <span style="line-height: 28px; margin-left: 5px">
        <el-button
          type="text"
          @click="refreshAction"
          :loading="loading">
          {{ loading ? '' : '刷新' }}
        </el-button>
      </span>
    </el-pagination>
  </div>
</template>

<script>
  import LbColumn from './lb-column';
  import SearchForm from '@/components/TableList/search/searchForm';
  import debounce from 'lodash/debounce';
  import _ from 'lodash'
  export default {
    props: {
      fields: Array,
      spanMethod: Function,
      pagination: {
        type: Boolean,
        default: false,
      },
      paginationTop: {
        type: String,
        default: '15px',
      },
      paginationAlign: {
        type: String,
        default: 'left',
      },
      merge: Array,
      searchFunc: {
        type: Function,
      },
      searchDefault: {
        type: Object,
        default: null,
      },
      pageSize: {
        type:Number,
        default:10
      },
      showExpandFormFlag:{
        type: Boolean,
        default: false,
      }
    },
    components: {
      LbColumn,
      SearchForm,
    },
    data() {
      return {
        mergeLine: {},
        mergeIndex: {},
        searchConditions: {},
        tableData: [],
        pageInfo: {
          pageSize: this.pageSize,
          currentPage: 1,
          pageOptions: [10, 20, 30, 40],
          total: 0,
        },
        loading: false,
        column: [],
      };
    },
    created() {
      this.init();
    },
    methods: {
      init() {
        this.initColumn();
        this.initPage();
        this.getTableData();
      },
      initColumn() {
        let fieldsList = [];
        this.fields.forEach(item => {
          if (
            typeof item.showField == 'undefined' ||
            (typeof item.showField != 'undefined' && item.showField === true)
          ) {
            fieldsList.push(item);
          }
        });
        this.$set(this, 'column', fieldsList);
      },
      initPage() {
        this.$set(this, 'pageInfo', {
          pageSize: this.pageSize,
          currentPage: 1,
          pageOptions: [10, 20, 30, 40, 100],
          total: 0,
        });
      },
      clearSelection() {
        this.$refs.elTable.clearSelection();
      },
      toggleRowSelection(row, selected) {
        this.$refs.elTable.toggleRowSelection(row, selected);
      },
      toggleAllSelection() {
        this.$refs.elTable.toggleAllSelection();
      },
      toggleRowExpansion(row, expanded) {
        this.$refs.elTable.toggleRowExpansion(row, expanded);
      },
      setCurrentRow(row) {
        this.$refs.elTable.setCurrentRow(row);
      },
      clearSort() {
        this.$refs.elTable.clearSort();
      },
      clearFilter(columnKey) {
        this.$refs.elTable.clearFilter(columnKey);
      },
      doLayout() {
        this.$refs.elTable.doLayout();
      },
      sort(prop, order) {
        this.$refs.elTable.sort(prop, order);
      },
      getMergeArr(tableData, merge) {
        if (!merge) return;
        this.mergeLine = {};
        this.mergeIndex = {};
        merge.forEach((item, k) => {
          tableData.forEach((data, i) => {
            if (i === 0) {
              this.mergeIndex[item] = this.mergeIndex[item] || [];
              this.mergeIndex[item].push(1);
              this.mergeLine[item] = 0;
            } else {
              if (data[item] === tableData[i - 1][item]) {
                this.mergeIndex[item][this.mergeLine[item]] += 1;
                this.mergeIndex[item].push(0);
              } else {
                this.mergeIndex[item].push(1);
                this.mergeLine[item] = i;
              }
            }
          });
        });
      },
      mergeMethod({ row, column, rowIndex, columnIndex }) {
        const index = this.merge.indexOf(column.property);
        if (index > -1) {
          const _row = this.mergeIndex[this.merge[index]][rowIndex];
          const _col = _row > 0 ? 1 : 0;
          return {
            rowspan: _row,
            colspan: _col,
          };
        }
      },
      getTableData: debounce(function () {
        this.loading = true;
        let where = this.searchConditions;
        this.searchFunc({
          where: where,
          page: this.pageInfo.currentPage,
          limit: this.pageInfo.pageSize,
          order: this.orderInfo,
        })
          .then(res => {
            this.$set(this, 'tableData', res.data.data);
            this.$set(this.pageInfo, 'total', res.data.total);
            this.loading = false;
          })
          .catch(() => {
            this.loading = false;
          });
      }, 300),
      handleSizeChange(val) {
        this.$set(this.pageInfo, 'currentPage', 1);
        this.$set(this.pageInfo, 'pageSize', val);
        this.getTableData();
      },
      handleCurrentChange(val) {
        this.$set(this.pageInfo, 'currentPage', val);
        this.getTableData();
      },
      refreshAction() {
        this.getTableData();
      },
      resetAction() {
        this.initPage();
        this.$set(this, 'searchConditions', this.searchConditions);
        this.getTableData();
      },
      haneleSearch(searchForm) {
        let conditions = {};
        this.column.forEach(item => {
          if (typeof searchForm[item.searchName] !== 'undefined') {
            if (item.exact == true) {
              conditions[item.searchName] = searchForm[item.searchName];
            } else {
              if (item.searchType == 'select') {
                conditions[item.searchName] = searchForm[item.searchName];
              }
              if (item.searchType == 'input') {
                conditions[item.searchName] = ['like', searchForm[item.searchName]];
              }
              if (item.searchType == 'dateTime' || item.searchType == 'date') {
                conditions[item.searchName] = ['between', searchForm[item.searchName]];
              }
            }
          } else {
            delete this.searchConditions[item.searchName];
          }
        });
        this.searchConditions = Object.assign(this.searchConditions, conditions);
        this.getTableData();
      },
      getTotal(param) {
        const { columns, data } = param;
        const sums = [];
        columns.forEach((column, index) => {
          if (index === 0) {
            sums[index] = '合计';
            return;
          }
          const values = data.map(item => Number(item[column.property]));
          let columnInfo = this.column.find( el => el.prop == column.property )
          if (columnInfo.showSummary) {
            sums[index] = values.reduce((prev, curr) => {
              const value = Number(curr);
              if (!isNaN(value)) {
                return _.add(prev,curr);
              } else {
                return prev;
              }
            }, 0);
            sums[index] = _.floor(sums[index], 4);
          } else {
            sums[index] = '--';
          }
        });
        return sums;
      },
    },
    watch: {
      merge() {
        this.getMergeArr(this.data, this.merge);
      },
      searchDefault: {
        handler(val) {
          if (val) {
            this.searchConditions = JSON.parse(JSON.stringify(val));
            this.$set(this, 'searchConditions', this.searchConditions);
          }
        },
        immediate: true,
      },
    },
  };
</script>
